#pragma strict

class LevelConfig {
	var patients:int[];
	var time_limit:float;
	var death_limit:int;
}

var font:Font;

var level_config_list:LevelConfig[];

var background_width:float;
var background_height:float;

var max_floors:int;
var patients_per_floor:int;

var first_bed_offset:Vector3;
var distance_between_beds:float;

var bed_transform:Transform;
var display_transform:Transform;
var display_text_transform:Transform;
var patient_increase_transform:Transform;
var patient_decrease_transform:Transform;

var player_prefab:Transform;
var elevator_prefab:Transform;

var patient_materials:Material[];

var floor_height:float;
var patients_dying:int;

var max_charge_level:float;

private var curr_charge_level:float;

private var curr_level:int;

private var time_count:float;

private static var instance:SceneManager;

// TODO transformar gameover em pause
private var gameover:boolean;
private var real_gameover:boolean;

private var is_active:boolean;

private var player_input_enabled:boolean;
private var player_animations_enabled:boolean;

private var dead_patients:int;

var gameover_prefab:Transform;

private var gameover_instance:Transform;

private var show_options_menu:boolean;
private var return_to_menu_confirmation:boolean;

private var current_level_config : LevelConfig[];

static function Instance() :SceneManager {	
	return instance;	
}

//achievements
private var achievement_no_dead:boolean;
private var achievement_oath:boolean;

function ResetLevel() {	
	show_options_menu = false;
	gameover = false;
	achievement_oath = false;
	for (var bed:GameObject in GameObject.FindGameObjectsWithTag("Bed")) {
		Destroy(bed);
	}
	for (var display:GameObject in GameObject.FindGameObjectsWithTag("Display")) {
		Destroy(display);
	}
	for (var patient:GameObject in GameObject.FindGameObjectsWithTag("Patient")) {
		Destroy(patient);	
	}	
	for (var player:GameObject in GameObject.FindGameObjectsWithTag("Player")) {
		Destroy(player);	
	}	
	
	for (var elevator:GameObject in GameObject.FindGameObjectsWithTag("Elevator")) {
		Destroy(elevator);	
	}
	if (gameover_instance != null) Destroy(gameover_instance.gameObject);
	
	Instantiate(player_prefab, player_prefab.position, Quaternion.identity);
	Instantiate(elevator_prefab, elevator_prefab.position, Quaternion.identity);
	
	curr_charge_level = 0;
	player_input_enabled = true;
	player_animations_enabled = true;
	is_active = false;
	
	dead_patients = 0;	
}

function LoadLevel(level:int) {
	ResetLevel();		
	if (CustomLevelManager.Instance().IsPlayingCustom()) {
		current_level_config = CustomLevelManager.Instance().GetCustomLevel();
	}	
	else {
		current_level_config = level_config_list;
	}
	
	var patients:int[] = current_level_config[curr_level].patients;	
	time_count = current_level_config[curr_level].time_limit;
	var i:int;
	var j:int;	
	for (i = 0; i < max_floors; i++) {
		for (j = 0; j < patients_per_floor; j++) {
			var bed_pos:Vector3 = first_bed_offset + Vector3(distance_between_beds * j, floor_height * i, 0);
			var patient_pos:Vector3;
			var display_pos:Vector3 = bed_pos;						
			var display_text_pos:Vector3 = bed_pos;						
			
			display_pos -= Vector3(display_transform.renderer.bounds.size.x, 0, 0);
					
			patient_pos = bed_pos;
			patient_pos.z = patient_increase_transform.position.z;
			
			var bed:Transform = Instantiate(bed_transform, bed_pos, Quaternion.identity);						
			var display:Transform = Instantiate(display_transform, display_pos, Quaternion.identity);									
			var display_text:Transform;
			
			
			var patient_type:int = patients[j + (i * patients_per_floor)];
			var patient:Transform;
			var patient_mat_index:int = Mathf.Round(Random.value * (patient_materials.length - 1));
			
			if (patient_type == 1) {
				//patient_pos = bed_pos + Vector3(0, bed_transform.localScale.y / 2 + patient_increase_transform.localScale.y / 2, 0);
				patient = Instantiate(patient_increase_transform, patient_pos, Quaternion.identity);
				Mathf.Round(Random.value * (patient_materials.length - 1));
				patient.renderer.material = patient_materials[patient_mat_index];
				display_text = Instantiate(display_text_transform, display_pos + Vector3(0,0,-1), Quaternion.identity);									
				display_text.parent = patient;
			}	
			else if (patient_type == 2) {
				//patient_pos = bed_pos + Vector3(0, bed_transform.localScale.y / 2 + patient_decrease_transform.localScale.y / 2, 0);
				patient = Instantiate(patient_decrease_transform, patient_pos, Quaternion.identity);
				Mathf.Round(Random.value * (patient_materials.length - 1));
				patient.renderer.material = patient_materials[patient_mat_index];
				display_text = Instantiate(display_text_transform, display_pos + Vector3(0,0,-1), Quaternion.identity);									
				display_text.parent = patient;
			}					
		}
	}
	patients_dying = 0;
}

function Start () {
	instance = this;
	gameover = false;
	LoadLevel(0);
	achievement_no_dead = false;	
}

function IsGameOver() : boolean {
	return gameover;
}

function GameOver() {
	gameover = true;
	DisablePlayerInput();
	DisablePlayerAnimations();
	//Time.timeScale = 0;
}

function GameResume() {
	gameover = false;
	EnablePlayerInput();
	EnablePlayerAnimations();
}

function GameEnded() {
	GameOver();
	for (var patient_tmp:GameObject in GameObject.FindGameObjectsWithTag("Patient")) {
		Destroy(patient_tmp.gameObject);	
	}
	// Desenha mensagem feliz na tela
	//Instantiate(victory_prefab);
	Application.LoadLevel("VictoryScene");
}

function LoadNextLevel() {	
	if (curr_level + 1 >= current_level_config.Length) {		
		GameEnded();
	}
	else {
		curr_level++;
		LoadLevel(curr_level);
	}
}

function RestartLevel() {
	LoadLevel(curr_level);
}

function Update () {	
	if (Input.GetButtonDown("Skip")) {
		LoadNextLevel();
	}
	else if (Input.GetButtonDown("Restart")) {
		RestartLevel();
	}	
	else if (!gameover) {
		time_count -= Time.deltaTime;
		if (time_count <= 0) {
			LoadNextLevel();
			if (dead_patients > 0) {
				ShowPopup(3, "You passed!\nThought "+dead_patients+" patients Passed away\nBut, Look on the bright side: all dead people were organ donors", true);
			} else {
				if (!achievement_no_dead) {
					ShowPopup(3, "Achievement Unlocked\nNone shall die!", true);
					achievement_no_dead = true;
				} else {
					ShowPopup(3, "You passed and no patients were harmed!", true);
				}
			}
			//GameOver();
		}			
	}	
	if (Input.GetButtonDown("Menu")) {		
		show_options_menu = !show_options_menu;
		if (show_options_menu) {
			GameOver();
		}
		else {
			GameResume();
		}
	}
}

function GetPlayer():GameObject {
	return GameObject.FindGameObjectWithTag("Player");
}

function GetElevator():GameObject {
	return GameObject.FindGameObjectWithTag("Elevator");
}

function GetCurrentTime() : int {
	return Mathf.Round(time_count);
}

function SetActive(val:boolean) {
	is_active = val;
	var player:GameObject = GameObject.FindGameObjectWithTag("Player");
	if (is_active) {
		SetPlayerInputEnabled(false);				
		player.rigidbody.velocity.x = 0;
	}
	else {
		SetPlayerInputEnabled(true);					
	}
}

function IsActive() : boolean {
	return is_active;
}

function DisablePlayerInput() {
	player_input_enabled = false;
}
function EnablePlayerInput() {
	player_input_enabled = true;
}

function IsPlayerInputEnabled() :boolean {
	return player_input_enabled;
}

function DisablePlayerAnimations() {
	player_animations_enabled = false;
}
function EnablePlayerAnimations() {
	player_animations_enabled = true;
}

function IsPlayerAnimationsEnabled() :boolean {
	return player_animations_enabled;
}

function SetPlayerInputEnabled(val:boolean) {
	player_input_enabled = val;
}

function GetDeathLimit() : int {
	return current_level_config[curr_level].death_limit;
}

function GetCurrentDeaths() : int {
	return dead_patients;
}

function GetCurrentLevel() : int {
	return curr_level;
}

function PatientDied() {
	dead_patients++;
	if (dead_patients > current_level_config[curr_level].death_limit) {
		GameOver();
		gameover_instance = Instantiate(gameover_prefab);
		real_gameover = true;
	}
}

function GetChargeLevel() : float {
	return curr_charge_level;
}

function GetMaxChargeLevel() : float {
	return max_charge_level;
}

function IsChargeFull() : boolean {
	if (curr_charge_level == max_charge_level) return true;
	else return false;
}

function AddCharge(val:float) {	
	curr_charge_level += val;
}

function RemoveCharge(val:float) {
	curr_charge_level -= val;
}

var mute:boolean = false;
var texture_music_on:Texture2D;
var texture_music_off:Texture2D;

function OnGUI() {	
	GUI.skin.button.alignment = TextAnchor.MiddleCenter;
	GUI.skin.label.alignment = TextAnchor.MiddleCenter;
	GUI.skin.label.font = font;
	GUI.skin.button.font = font;
	GUI.skin.label.fontSize = 16;
	GUI.skin.button.fontSize = 16;
	
	var sound_button_image:Texture = texture_music_on;
	if (mute)
		sound_button_image = texture_music_off;

	if (GUI.Button( Rect(Screen.width-40,0,40,40), sound_button_image)) {
		mute = !mute;
		var audio:AudioSource = GameObject.FindGameObjectWithTag("Music").audio;
		if (audio.isPlaying)
			audio.Stop();
		else
			audio.Play();
	}
	if (show_options_menu) {		
		ShowMenu();
	}
}

function ReturnToMenu() {
	if (CustomLevelManager.Instance().IsPlayingCustom()) {
		Application.LoadLevel("CustomLevelScene");
	}
	else {
		Application.LoadLevel("MenuScene");
	}
}

function ShowReturnToMenuConfirmation() {	
	var area_width = background_width / 4;
	var area_height = background_height / 4;
	var area_start_x = background_width / 2 - area_width / 2;
	var area_start_y = background_height / 2 - area_height / 2;
	GUILayout.BeginArea(Rect(area_start_x, area_start_y, area_width, area_height));
		GUILayout.BeginVertical("box");
			GUILayout.Label("Do you really want to return to the menu?\n All your progress will be lost");
			if (GUILayout.Button("Yes")) {
				ReturnToMenu();
			}
			if (GUILayout.Button("No")) {			
				return_to_menu_confirmation = false;				
			}
		GUILayout.EndArea();
	GUILayout.EndVertical();
}

function ShowMenu() {		
	var area_width = background_width / 4;
	var area_height = background_height / 4;
	var area_start_x = background_width / 2 - area_width / 2;
	var area_start_y = background_height / 2 - area_height / 2;
	GUILayout.BeginArea(Rect(area_start_x, area_start_y, area_width, area_height));			
		GUILayout.BeginVertical("box");
		if (return_to_menu_confirmation) GUI.enabled = false;
			if (GUILayout.Button("Restart Level")) {
				RestartLevel();
			}
			if (GUILayout.Button("Exit")) {			
				return_to_menu_confirmation = true;				
			}			
			GUILayout.Label("");			
			if (GUILayout.Button("Resume")) {			
				show_options_menu = false;
				if (!real_gameover) GameResume();
			}
		GUILayout.EndVertical();	
	GUILayout.EndArea();
	GUI.enabled = true;
	if (return_to_menu_confirmation) {
		ShowReturnToMenuConfirmation();
	}		
}

var popup:Transform;

function ShowPopup(time:int, text:String, pause:boolean) {	
	if (pause) GameOver();
	var popup_inst:Transform = Instantiate(popup);
	var popup_script:Popup = popup_inst.GetComponent("Popup") as Popup;
	popup_script.popup_height = 200;
	popup_script.popup_width = 400;
	popup_script.popup_text = text;
	popup_script.popup_time_limit = time;	
	popup_script.popup_resume_game = pause;
}

function PopupEnded(resume:boolean)
{
	if (resume) GameResume();
}

function PatientKilledByMedic() {
	if (!achievement_oath) {
		achievement_oath = true;
		ShowPopup(3, "Achievement Unlocked\nHippocratic Oath!", false);				
	}
}